#include "List.h"

void ListInit(ListNode** pphead)
{
    assert(pphead);
    *pphead = (ListNode*)malloc(sizeof(ListNode));
    assert(*pphead);
    (*pphead)->next = *pphead;
    (*pphead)->prev = *pphead;
}

void ListDestory(ListNode** pphead)
{
    assert(pphead);
    ListNode* curr = (*pphead)->next;
    //while (curr != *pphead)
    //{
    //    ListNode* next = curr->next;
    //    free(curr);
    //    curr = next;
    //}
    
    while ((*pphead)->next != *pphead)
        ListPopBack(*pphead);

    free(*pphead);
    *pphead = nullptr;
}

void ListPushFront(ListNode* phead, LTDataType val)
{
    assert(phead);
    ListInsert(val, phead->next);
    //ListNode* newNode = BuyNode(val);
    //newNode->next = phead->next;
    //phead->next->prev = newNode;
    //phead->next = newNode;
    //newNode->prev = phead;
}

void ListPushBack(ListNode* phead, LTDataType val)
{
    assert(phead);
    ListInsert(val, phead);
    //ListNode* newNode = BuyNode(val);
    //newNode->prev = phead->prev;
    //phead->prev->next = newNode;
    //phead->prev = newNode;
    //newNode->next = phead;
}

void ListInsert(LTDataType val, ListNode* pos)
{
    assert(pos);
    ListNode* newNode = BuyNode(val);
    newNode->prev = pos->prev;
    pos->prev->next = newNode;
    pos->prev = newNode;
    newNode->next = pos;
}

void ListPopFront(ListNode* phead)
{
    assert(phead);
    assert(!ListEmpty(phead));
    //assert(phead != phead->next);
    ListErase(phead->next);
    //ListNode* del = phead->next;
    //phead->next = del->next;
    //del->next->prev = phead;
    //free(del);
}

void ListPopBack(ListNode* phead)
{
    assert(phead);
    assert(!ListEmpty(phead));
    //assert(phead != phead->prev);
    ListErase(phead->prev);
    //ListNode* del = phead->prev;
    //phead->prev = del->prev;
    //del->prev->next = phead;
}

void ListErase(ListNode* pos)
{
    assert(pos->next != pos);
    ListNode* prev = pos->prev;
    prev->next = pos->next;
    pos->next->prev = prev;
}

ListNode* ListFind(ListNode* phead, LTDataType val)
{
    assert(phead);
    ListNode* curr = phead->next;
    while (curr != phead)
    {
        if (curr->val == val)
            return curr;
        curr = curr->next;
    }
    return nullptr;
}

void ListPrint(ListNode* phead)
{
    assert(phead);
    ListNode* curr = phead->next;
    while (curr != phead)
    {
        printf("%d ", curr->val);
        curr = curr->next;
    }
    printf("\n");
}

bool ListEmpty(ListNode* phead)
{
    assert(phead);
    return phead == phead->next;
}

size_t ListSize(ListNode* phead)
{
    assert(phead);
    ListNode* curr = phead->next;
    size_t size = 0;
    while (curr != phead)
    {
        size++;
        curr = curr->next;
    }

    return size;
}

ListNode* BuyNode(LTDataType val)
{
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
    assert(newNode);
    newNode->val = val;
    newNode->prev = newNode;
    newNode->next = newNode;
    return newNode;
}